using System.Collections.Generic;
using System.Linq;

namespace Arcane.Source.Utils
{
    // Immutable dictionary.
    public class Msg
    {
        private readonly Dictionary<string, object> _entries;
        private Msg(Dictionary<string, object> entries)
        {
            _entries = entries;
        }

        public static Msg Empty() => new([]);

        public static Msg Single<T>(string key, T item) => Create().Put(key, item).Wrap();

        public static Builder Create() => new();

        public T Get<T>(string key)
        {
            if (_entries.TryGetValue(key, out var obj) && obj is T target)
            {
                return target;
            }
            return default;
        }

        public bool TryGet<T>(string key, out T value)
        {
            if (_entries.TryGetValue(key, out var obj) && obj is T target)
            {
                value = target;
                return true;
            }
            value = default;
            return false;
        }

        public override string ToString() => $"{{{string.Join(",", _entries.Select((kv) => $"{kv.Key}:{kv.Value}"))}}}";

        public class Builder
        {
            private Dictionary<string, object> _entries;

            public Builder()
            {
                _entries = [];
            }

            public Builder Put<T>(string key, T item)
            {
                _entries.Add(key, item);
                return this;
            }

            public Msg Wrap()
            {
                return new(_entries);
            }
        }
    }
}